#ifndef UUID_3F7736ECFB5F48F0C02092BA86F87D0E
#define UUID_3F7736ECFB5F48F0C02092BA86F87D0E

#include "../gvl/support/cstdint.hpp"
#include "../gvl/support/platform.hpp"

#ifdef __cplusplus
extern "C" {
#endif

typedef uint32_t flip_color;

GVL_INLINE flip_color flip_rgba(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
{
	return r | (g << 8) | (b << 16) | (a << 24);
}

GVL_INLINE flip_color flip_get_r(flip_color c)
{ return c & 0xff; }

GVL_INLINE flip_color flip_get_g(flip_color c)
{ return (c >> 8) & 0xff; }

GVL_INLINE flip_color flip_get_b(flip_color c)
{ return (c >> 16) & 0xff; }

GVL_INLINE flip_color flip_get_a(flip_color c)
{ return (c >> 24) & 0xff; }

GVL_INLINE flip_color flip_scale_color(flip_color c, int factor)
{
	uint32_t temp1 = c & 0xFF00FF;
	uint32_t temp2 = c & 0x00FF00;
	
	temp1 = (temp1 * factor) & 0xFF00FF00;
	temp2 = (temp2 * factor) & 0x00FF0000;
	
	return (temp1 | temp2) >> 8;
}

GVL_INLINE flip_color flip_scale_color_half(flip_color c)
{
	return ((c & 0xFEFEFE) >> 1);
}

GVL_INLINE flip_color flip_invert_color(flip_color c)
{
	return 0xffffff - c;
}

GVL_INLINE flip_color flip_scale_darkness(flip_color c, int factor)
{
	return flip_invert_color(flip_scale_color(flip_invert_color(c), factor));
}
	
GVL_INLINE flip_color flip_add_colors_crude(flip_color c1, flip_color c2)
{
	uint32_t color1 = (c1 & 0xFEFEFF) + (c2 & 0xFEFEFF);
	uint32_t temp1 = (color1 & 0x01010100) >> 7;
	color1 |= 0x010101 - temp1;
	return (color1 & 0xFFFFFF);
}

GVL_INLINE flip_color flip_blend_colors(flip_color c1, flip_color c2, int factor)
{
	flip_color res = (((c2 & 0xFF00FF) - (c1 & 0xFF00FF)) * factor >> 8) + c1;
	flip_color g;
	c1 &= 0xFF00;
	c2 &= 0xFF00;
	g = ((c2 - c1) * factor >> 8) + c1;
	
	res &= 0xFF00FF;
	g &= 0xFF00;
	
	return res | g;
}

GVL_INLINE flip_color flip_blend_colors_half(flip_color c1, flip_color c2)
{
	return ((c1 & 0xFEFEFE) >> 1)
	     + ((c2 & 0xFEFEFE) >> 1)
	     + (c1 & c2 & 0x010101);
}

GVL_INLINE flip_color flip_blend_16_colors(flip_color c[16])
{
	flip_color rbsum = 0, gsum = 0;
	int i;
	
	for(i = 0; i < 16; ++i)
	{
		rbsum += c[i] & 0xff00ff;
		gsum += c[i] & 0x00ff00;
	}
	
	return ((rbsum >> 4) & 0xff00ff) | ((gsum >> 4) & 0x00ff00);
}

GVL_INLINE flip_color flip_blend_8_colors(flip_color c[8])
{
	flip_color rbsum = 0, gsum = 0;
	int i;
	
	for(i = 0; i < 8; ++i)
	{
		rbsum += c[i] & 0xff00ff;
		gsum += c[i] & 0x00ff00;
	}
	
	return ((rbsum >> 3) & 0xff00ff) | ((gsum >> 3) & 0x00ff00);
}

flip_color flip_hsv(double h, double s, double v);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // UUID_3F7736ECFB5F48F0C02092BA86F87D0E
